﻿/***************************************************************************/
/// <summary>
///  <title>SLIC LogOnController</title>
///  <description>LogOnController for LogOn LogOff actions</description>
///  <copyRight>Copyright (c) 2011</copyRight>
///  <company>IronOne Technologies (Pvt)Ltd</company>
///  <createdOn>2011-08-01</createdOn>
///  <author>Lushanthan Sivaneasharajah</author>
///  <modification>
///     <modifiedBy></modifiedBy>
///      <modifiedDate></modifiedDate>
///     <description></description>
///  </modification>
/// </summary>
/// 
/***************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Data;

#region SLICReferences
using SLIC.Models;
using SLIC.Models.Auth;
using SLIC.Models.Enums;
//using SLIC.Models.Entity;
#endregion SLICReferences

#region ThirdPartyReferences
using log4net;
#endregion ThirdPartyReferences


namespace SLIC.Controllers
{    
    public class LogOnController : BaseController
    {
        protected static readonly ILog log = LogManager.GetLogger("root");

        AccountMembershipService MembershipService = new AccountMembershipService();
        FormsAuthenticationService FormsService = new FormsAuthenticationService();


        ///GetUserGuid return method
        ///<returns>
        ///Returns the GUID of the current user
        ///</returns>       
        ///<exception cref="">
        ///
        /// </exception>
        /// <remarks>NOT USED IN THIS PROJECT!!!</remarks>
        public Guid GetUserGuid()
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get User Guid,");
            Guid a = new Guid();
            //foreach (var item in allusers)
            //{
            //    if (Membership.GetUser().UserName == item.UserName)
            //        a = (Guid)item.UserId; break;
            //}
            try
            {
                a = (Guid)(Membership.GetUser().ProviderUserKey);
                log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get User Guid,");
            }
            catch (Exception e)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Get User Guid,");
                throw;
            }

            return a;
        }



        ///LogOn Action Method
        ///<param name="model">LogOnModel</param>
        ///<param name="returnUrl">return URL</param>
        ///<returns>
        ///If successfully logged on goes to Default/Index or the return url
        ///</returns>       
        ///<exception cref="">
        ///Same view with the error
        /// </exception>
        /// <remarks></remarks>
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log On," + User.Identity.Name + ", [Params=( User name:" + model.UserName + ",Return Url: " + returnUrl + ",Client IP:"+ Request.ServerVariables["REMOTE_ADDR"]+")]");
           
            if (User.Identity.IsAuthenticated)
            {
                return RedirectToAction("Index", "Default");
            }

            try
            {
                if (model.UserName == null && model.Password == null)
                {
                    if (Request.Params.Get("fmt") == "xml" || Request.Params.Get("fmt") == "XML")
                        throw new GenException(101, "Please Log in.");
                    else
                        throw new GenException(101, "");                   
                }
                else if (model.UserName == null) throw new GenException(102, "Username cannot be empty");
                else if (model.Password == null) throw new GenException(103, "Password cannot be empty");

                if (ModelState.IsValid)
                {  
                    MembershipUser mUser = Membership.GetUser(model.UserName);

                    //Error messages should not give any useful information - security check!
                    //if (mUser == null)
                    //{
                    //    throw new GenException(106, "User name not found.");
                    //}

                    if (mUser != null && mUser.IsLockedOut)
                    {
                        throw new GenException(105, "Your account has been locked. Please contact the administrator.");
                    }
                   
                    if (MembershipService.ValidateUser(model.UserName, model.Password))
                    {
                        FormsService.SignIn(model.UserName, model.RememberMe);

                        log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log On," + User.Identity.Name + ", [Params=( User name:" + model.UserName + ",Return Url: " + returnUrl + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");

                        // Add format to session
                        Session.Add("fmt", Request.Params.Get("fmt"));

                        if (!String.IsNullOrEmpty(returnUrl))
                        {
                            return Redirect(returnUrl);
                        }
                        else
                        {
                            return RedirectToAction("Index", "Default");
                        }
                    }
                    else
                    {
                        //log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",LogOn," + User.Identity.Name + ",Incorrect User Name or Password.");
                        throw new GenException(104, "Incorrect User Name or Password");
                    }
                }
            }
            catch (GenException ex)
            {
                ModelState.AddModelError("err", ex);
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log On," + User.Identity.Name + "," + ex.Message);
            }
            //catch (EntityException ex)
            //{
            //    ModelState.AddModelError("err", new GenException(801, "Error occured while connecting to the entity database.Please try again later"));
            //    log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",LogOn," + User.Identity.Name +  "," + ex.Message);               
            //}
            catch (SqlException ex)
            {
                ModelState.AddModelError("err", new GenException(803, "SQL Server Timeout, Please try again later"));
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log On," + User.Identity.Name + "," + ex.Message);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("err", new GenException(111, ex.Message));
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log On," + User.Identity.Name + "," + ex.Message);
            }
            return GetFormatView("Account/LogOn.aspx");
        }

        public ActionResult LogOff()
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log Off," + User.Identity.Name + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            FormsService.SignOut();
            log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Log Off," + User.Identity.Name + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            return RedirectToAction("Index", "Default");
            //return RedirectToAction("LogOn");
        }

        public ActionResult NotAuthorized()
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Not Authorized," + User.Identity.Name + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            return GetFormatView("Account/NotAuthorized.aspx");
        }

        //public ActionResult ResetPassword()
        //{
        //    return GetFormatView("Account/ViewPage1.aspx");
        //}
        #region PasswordManagement

        #region ChangePassword
        [Authorize]
        public ActionResult ChangePassword()
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Change Password," + User.Identity.Name);
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return GetFormatView("Account/ChangePassword.aspx");
        }

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Change Password," + User.Identity.Name + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            try
            {
                if (ModelState.IsValid)
                {
                    if (MembershipService.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword))
                    {
                        throw new GenException(120, "Password changed successfully.");
                        //return RedirectToAction("ResetPasswordSuccess");
                    }
                    else
                    {
                        ModelState.AddModelError("err", new GenException(121, "The current password is incorrect or the new password is invalid."));
                    }
                }
            }
            catch (GenException ex)
            {
                ModelState.AddModelError("err", ex);
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Change Password," + User.Identity.Name + "," + ex.Message + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            }
            catch (EntityException ex)
            {
                ModelState.AddModelError("err", new GenException(801, "Error occured while connecting to the entity database.Please try again later"));
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Change Password," + User.Identity.Name+",ClientIP:" +  "," + ex.Message+", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            }
            catch (SqlException ex)
            {
                ModelState.AddModelError("err", new GenException(803, "SQL Server Timeout, Please try again later"));
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Change Password," + User.Identity.Name + ",ClientIP:" + "," + ex.Message + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("err", new GenException(111, ex.Message));
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Change Password," + User.Identity.Name + "," + ex.Message + ", [Params=( Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            }

            // If we got this far, something failed, redisplay form
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return GetFormatView("Account/ChangePassword.aspx", model);
            //return View(model);
        }

        public ActionResult ChangePasswordSuccess()
        {
            return GetFormatView("Account/ViewPage2.aspx");
            // return View();
        }
        #endregion ChangePassword

        #endregion PasswordManagement
    }
}
